package com.lfk.justwetools.Utils;

import ohos.agp.colors.RgbColor;
import ohos.agp.render.*;
import ohos.media.image.PixelMap;
import ohos.agp.utils.Color;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Rect;
import ohos.media.image.common.Size;

import java.util.Arrays;

/**
 * Created by liufengkai on 15/11/10.
 */
public class ImageHelper {

    /**
     * Set the rotation on a color axis by the specified values.
     * <p>
     * <code>axis=0</code> correspond to a rotation around the RED color
     * <code>axis=1</code> correspond to a rotation around the GREEN color
     * <code>axis=2</code> correspond to a rotation around the BLUE color
     * </p>
     */
    private static void rotateColorMatrix(ColorMatrix colorMatrix, int axis, float degrees) {
        colorMatrix.reset();
        float[] matrix = colorMatrix.getMatrix();

        double radians = degrees * Math.PI / 180d;
        float cosine = (float) Math.cos(radians);
        float sine = (float) Math.sin(radians);
        switch (axis) {
            // Rotation around the red color
            case 0:
                matrix[6] = matrix[12] = cosine;
                matrix[7] = sine;
                matrix[11] = -sine;
                break;
            // Rotation around the green color
            case 1:
                matrix[0] = matrix[12] = cosine;
                matrix[2] = -sine;
                matrix[10] = sine;
                break;
            // Rotation around the blue color
            case 2:
                matrix[0] = matrix[6] = cosine;
                matrix[1] = sine;
                matrix[5] = -sine;
                break;
            default:
                throw new RuntimeException();
        }
        colorMatrix.setMatrix(matrix);
    }

    /**
     * 设置图片的色调\饱和度\亮度
     *
     * @param bm
     * @param hue        色调
     * @param saturation 饱和度
     * @param lum        亮度
     * @return
     */
    public static PixelMap handleImageEffect(PixelMap bm,
                                           float hue,
                                           float saturation,
                                           float lum) {
        PixelMap.InitializationOptions options = new PixelMap.InitializationOptions();
        options.pixelFormat = PixelFormat.ARGB_8888;
        options.size = bm.getImageInfo().size;
        options.editable = true;
        PixelMap bmp = PixelMap.create(options);

        Texture texture = new Texture(bmp);
        Canvas canvas = new Canvas(texture);
        Paint paint = new Paint();

        ColorMatrix hueMatrix = new ColorMatrix();
        rotateColorMatrix(hueMatrix, 0, hue);
        rotateColorMatrix(hueMatrix, 1, hue);
        rotateColorMatrix(hueMatrix, 2, hue);

        ColorMatrix saturationMatrix = new ColorMatrix();
        saturationMatrix.setSaturation(saturation);

        ColorMatrix lumMatrix = new ColorMatrix();
        lumMatrix.setScale(lum, lum, lum, 1);

        ColorMatrix imageMatrix = new ColorMatrix();
        imageMatrix.postConcat(hueMatrix);
        imageMatrix.postConcat(saturationMatrix);
        imageMatrix.postConcat(lumMatrix);

        paint.setColorMatrix(imageMatrix);

        PixelMapHolder holder = new PixelMapHolder(bm);
        canvas.drawPixelMapHolder(holder, 0, 0, paint);
        return bmp;
    }

    public static PixelMap handleImagePixelsOldPhoto(PixelMap bm) {
        PixelMap.InitializationOptions options = new PixelMap.InitializationOptions();
        options.pixelFormat = PixelFormat.ARGB_8888;
        options.size = bm.getImageInfo().size;
        options.editable = true;
        PixelMap bmp = PixelMap.create(options);
        int width = options.size.width;
        int height = options.size.height;
        int color = 0;
        int r, g, b, a, r1, g1, b1;

        int[] oldPx = new int[width * height];
        int[] newPx = new int[width * height];

        bm.readPixels(oldPx, 0, options.size.width, new Rect(0, 0, width, height));
        for (int i = 0; i < width * height; i++) {
            color = oldPx[i];
            RgbColor rgbColor = new RgbColor(color);
            a = rgbColor.getAlpha();
            r = rgbColor.getRed();
            g = rgbColor.getGreen();
            b = rgbColor.getBlue();

            r1 = (int) (0.393 * r + 0.769 * g + 0.189 * b);
            g1 = (int) (0.349 * r + 0.686 * g + 0.168 * b);
            b1 = (int) (0.272 * r + 0.534 * g + 0.131 * b);

            if (r1 > 255) {
                r1 = 255;
            }
            if (g1 > 255) {
                g1 = 255;
            }
            if (b1 > 255) {
                b1 = 255;
            }

            newPx[i] = Color.argb(a, r1, g1, b1);
        }
        bmp.writePixels(newPx, 0, width, new Rect(0, 0, width, height));
        return bmp;
    }

    public static PixelMap handleImagePixelsRelief(PixelMap bm) {
        PixelMap.InitializationOptions options = new PixelMap.InitializationOptions();
        options.pixelFormat = PixelFormat.ARGB_8888;
        options.size = bm.getImageInfo().size;
        options.editable = true;
        PixelMap bmp = PixelMap.create(options);
        int width = options.size.width;
        int height = options.size.height;
        int color = 0, colorBefore = 0;
        int a, r, g, b;
        int r1, g1, b1;

        int[] oldPx = new int[width * height];
        int[] newPx = new int[width * height];

        bm.readPixels(oldPx, 0, width, new Rect(0, 0, width, height));
        for (int i = 1; i < width * height; i++) {
            colorBefore = oldPx[i - 1];
            RgbColor rgbColor = new RgbColor(colorBefore);
            a = rgbColor.getAlpha();
            r = rgbColor.getRed();
            g = rgbColor.getGreen();
            b = rgbColor.getBlue();

            color = oldPx[i];
            rgbColor = new RgbColor(color);
            r1 = rgbColor.getRed();
            g1 = rgbColor.getGreen();
            b1 = rgbColor.getBlue();

            r = (r - r1 + 127);
            g = (g - g1 + 127);
            b = (b - b1 + 127);
            if (r > 255) {
                r = 255;
            }
            if (g > 255) {
                g = 255;
            }
            if (b > 255) {
                b = 255;
            }
            newPx[i] = Color.argb(a, r, g, b);
        }
        bmp.writePixels(newPx, 0, width, new Rect(0, 0, width, height));
        return bmp;
    }
}
